﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LCA.Community.Web.Filters;
using LCA.Community.DAL.Model;
using Microsoft.Practices.Unity;
using LCA.Community.DAL.Interfaces;

namespace LCA.Community.Web.Controllers
{
    /// <summary>
    /// Controller for managing events.
    /// </summary>
    public class EventsController : BaseController
    {

        /// <summary>
        /// Actions for showing the events of a group.
        /// </summary>
        /// <param name="id">The group id.</param>
        /// <returns>The view showing the events of a group.</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NotLoggedIn")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "GroupNotFound", 2)]
        public ActionResult Index(string id)
        {
            var group = GroupsRepository.Get(id);
            var nextEvents = EventsRepository.GetNextGroupEvents(id,20);

            ViewData["owner"] = IsGroupOwner(id);
            ViewData["member"] = IsGroupMember(id);
            ViewData["group"] = group;
            ViewData["date"] = DateTime.Now;

            return View("Index", nextEvents);
        }

        /// <summary>
        /// Action for showing an event in detail
        /// </summary>
        /// <param name="id">The event id</param>
        /// <returns>View showing the details of the event.</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NotLoggedIn")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "EventNotFound", 2)]
        public ActionResult Details(string id)
        {
            var lcaEvent = EventsRepository.Get(id);
            var group = GroupsRepository.Get(lcaEvent.PartitionKey);
            ViewData["owner"] = IsGroupOwner(lcaEvent.PartitionKey);
            ViewData["member"] = IsGroupMember(lcaEvent.PartitionKey);
            ViewData["groupID"] = lcaEvent.PartitionKey;
            ViewData["group"] = group;
            return View("Details", lcaEvent);
        }

        /// <summary>Action for showing the events of a group on a specific month.</summary>
        /// <param name="id">The group id.</param>
        /// <param name="month">The month.</param>
        /// <param name="year">The year.</param>
        /// <returns>View showing the events of a group on a specific month.</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NotLoggedIn")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "GroupNotFound", 2)]
        public ActionResult ShowMonth(string id, int month, int year)
        {
            var partialView = new PartialViewResult();
            partialView.ViewName = "ShowCalendar";
            partialView.ViewData.Model = EventsRepository.GetEventsByGroup(id);
            partialView.ViewData["date"] = new DateTime(year, month, 1);
            return partialView;
        }

        /// <summary> Action for creating a new event.</summary>
        /// <param name="id">The group id.</param>
        /// <returns>View for creating a new event.</returns>
        [SecurityFilter(SecurityRequisites = "GroupOwner", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "GroupNotFound", 2)]
        public ActionResult Create(string id)
        {
            ViewData["group"] = GroupsRepository.Get(id);
            ViewData["groupname"] = id;
            ViewData["owner"] = IsGroupOwner(id);
            ViewData["member"] = IsGroupMember(id);
            return View("Create", new Event());
        }


        /// <summary>
        /// Action for creating an event.
        /// </summary>
        /// <param name="id">The group id.</param>
        /// <param name="lcaEvent">The event.</param>
        /// <returns>If the event could be added return the view showing the events of the group, otherwise it returns the view for creating an event.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "GroupOwner", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "GroupNotFound", 2)]
        public ActionResult Create(string id, Event lcaEvent)
        {
            if (ModelState.IsValid)
            {
                lcaEvent.RowKey = Guid.NewGuid().ToString();
                lcaEvent.PartitionKey = id;
                EventsRepository.Add(lcaEvent);

                return RedirectToAction("Index", new { id = lcaEvent.PartitionKey });
            }

            ViewData["group"] = GroupsRepository.Get(id);
            ViewData["groupname"] = id;
            ViewData["owner"] = IsGroupOwner(id);
            ViewData["member"] = IsGroupMember(id);
            return View("Create", lcaEvent);
        }

        /// <summary>
        /// Action for editing an event.
        /// </summary>
        /// <param name="eventID">The event ID.</param>
        /// <param name="groupID">The group ID.</param>
        /// <returns>View for editing an event.</returns>
        [SecurityFilter(SecurityRequisites = "GroupOwner", SolvingActionParameter = "groupID", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "EventNotFound", 2)]
        public ActionResult Edit(string eventID, string groupID)
        {
            ViewData["group"] = GroupsRepository.Get(groupID);
            ViewData["groupname"] = groupID;
            ViewData["owner"] = IsGroupOwner(groupID);
            ViewData["member"] = IsGroupMember(groupID);
            return View("Edit", EventsRepository.Get(eventID));
        }

        /// <summary>
        /// Action for editing an event.
        /// </summary>
        /// <param name="eventID">The event ID.</param>
        /// <param name="groupID">The group ID.</param>
        /// <param name="ev">The event.</param>
        /// <returns>If the event could be edited return the view showing the events of the group, otherwise it returns the view for editing an event.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "GroupOwner", SolvingActionParameter = "groupID", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "EventNotFound", 2)]
        public ActionResult Edit(string eventID, string groupID, Event lcaEvent)
        {
            if (ModelState.IsValid)
            {
                lcaEvent.RowKey = eventID;
                lcaEvent.PartitionKey = groupID;
                EventsRepository.Update(lcaEvent);

                return RedirectToAction("Index", new { id = lcaEvent.PartitionKey });
            }

            ViewData["group"] = GroupsRepository.Get(groupID);
            ViewData["groupname"] = groupID;
            ViewData["owner"] = IsGroupOwner(groupID);
            ViewData["member"] = IsGroupMember(groupID);
            return View("Edit", lcaEvent);
        }

        /// <summary>
        /// Elimina el evento con la id proporcionada.
        /// </summary>
        /// <returns></returns>
        [SecurityFilter(SecurityRequisites = "GroupOwner", SolvingActionParameter = "groupID", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "EventNotFound", 2)]
        public ActionResult Remove(string eventID, string groupID)
        {
            Event lcaevent = EventsRepository.Get(eventID);
            EventsRepository.Delete(lcaevent);
            
            if(IsAdmin(UserID))
                return RedirectToAction("Index", "Admin");
            else
                return RedirectToAction("Index", "Events", lcaevent.PartitionKey);
        }

        [Dependency]
        public IEventsRepository EventsRepository { get; set; }
    }
}
